from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from urllib import unquote, quote
from urlparse import urljoin
from BeautifulSoup import BeautifulSoup
from base64 import urlsafe_b64decode, urlsafe_b64encode
import logging, re
slug_re_obj = re.compile(r'^[\w=-]+$')
charset_re_obj = re.compile(r'charset=([\w-]+)')
charset_re_obj_in_html = re.compile(r'\<\s*meta.+?charset=([\w-]+).*?\>', flags = re.IGNORECASE)
def log(msg):
    logging.info(msg)

def url2slug(url):
    if type(url) == str:
        slug = urlsafe_b64encode(url)
    elif type(url) == unicode:
        slug = urlsafe_b64encode(url.encode('utf-8'))
    return '/to/%s' % slug

class MainPage(webapp.RequestHandler):
    def get(self):
        self.response.out.write("""
      <html>
        <body>
          <form action="." method="post">
            <div><input id="site" name="site" type="text" /><input type="submit" value="Break" /></div>
          </form>
        </body>
      </html>""")

    def post(self):
        url = self.request.get('site')
        if not url.startswith('http'):
            url = 'http://' + url
        slug = url2slug(url)
        self.redirect(slug)

def unquoted_full_url(url, query_string):
    if query_string:
        url = url + '?%s' % query_string
    return unquote(url)

class OutSiteUrl(webapp.RequestHandler):
    def get(self, url):
        referer_url = self.request.headers.get('Referer', '')
        url = unquoted_full_url(url, self.request.query_string)
        if referer_url:
            referer_site_url = urlsafe_b64decode(referer_url.split('/')[-1])
            self.redirect(url2slug(urljoin(referer_site_url, '/' + url)))
        elif url.startswith('http'):
            self.redirect(url2slug(url))
        else:
            self.error(404)
            

class WallBreak(webapp.RequestHandler):
    def get(self, slug):
        unquoted_slug = unquote(slug)
        #log('unquoted ' + unquoted_slug)
        if slug_re_obj.match(unquoted_slug):
            url = urlsafe_b64decode(unquoted_slug)
        else:
            referer_url = self.request.headers.get('Referer', '')
            if referer_url:
                referer_site_url = urlsafe_b64decode(referer_url.split('/')[-1])
                full_url = unquoted_full_url(slug, self.request.query_string)
                self.redirect(url2slug(urljoin(referer_site_url, full_url)))
            else:
                self.error(404)
            return
        #log('decoded ' + url)
        #log('Referer ' + referer_site_url)
        result = urlfetch.fetch(url = url,
                                method=urlfetch.GET,
                                )
        #log('fetched ' + url)
        content_type = result.headers.get('content-type', '')
        self.response.headers["Content-Type"] = content_type
        self.response.out.write(result.content)
#        if 'text/html' in content_type:
#            charset_match = charset_re_obj.search(content_type)
#            if charset_match:
#                charset = charset_match.group(1)
#            else:
#                log(result.status_code)
#                charset_match_in_html = charset_re_obj_in_html.search(result.content)
#                if charset_match_in_html:
#                    charset = charset_match_in_html.group(1)
#                    self.response.headers["Content-Type"] += "; charset=%s" % charset
#                else:
#                    charset = None
#            log('charset ' + charset)
#            soup = BeautifulSoup(result.content, fromEncoding = charset)
#            log('originalEncoding ' + soup.originalEncoding)
#            anchors = soup.findAll('a')
#            for a in anchors:
#                href = a.get('href')
#                if href:
#                    new_url = url2slug(urljoin(url, href))
#                    a['href'] = new_url
#            images = soup.findAll('img')
#            for image in images:
#                src = image.get('src')
#                if src:
#                    new_url = url2slug(urljoin(url, src))
#                    image['src'] = new_url
#            scripts = soup.findAll('script')
#            for image in scripts:
#                src = image.get('src')
#                if src:
#                    new_url = url2slug(urljoin(url, src))
#                    image['src'] = new_url
#            links = soup.findAll('link')
#            for a in links:
#                href = a.get('href')
#                if href:
#                    new_url = url2slug(urljoin(url, href))
#                    a['href'] = new_url
#            self.response.out.write(soup.renderContents(encoding = charset or "utf-8"))
#        else:
#            self.response.out.write(result.content)
    def post(self, url):
        pass
    
application = webapp.WSGIApplication([('/$', MainPage),
                                      (r'/to/(.*)', WallBreak),
                                      (r'/(.*)', OutSiteUrl)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()